// // import WinPanel from "../../../Script/UI/WinPanel";

import { _decorator, AudioClip, Component, director, Node } from 'cc';
const { ccclass, property, executionOrder } = _decorator;

import { SSS_Consts } from "../../../Script/Data/SSS_Consts";
import { bdlMgr } from "../../../Script/Manager/BundleManager_S";
import UI from "../../../Script/Manager/UI";
import ShuZiHuaRongDao_Block from "./ShuZiHuaRongDao_Block";
import { ShuZiHuaRongDao_GameData } from "./ShuZiHuaRongDao_GameData";
import ShuZiHuaRongDao_GameFunction from "./ShuZiHuaRongDao_GameFunction";
import ShuZiHuaRongDao_GamePanel from "./ShuZiHuaRongDao_GamePanel";
import { ShuZiHuaRongDao_GameStorage } from "./ShuZiHuaRongDao_GameStorage";
import { ShuZiHuaRongDao_Timer } from "./ShuZiHuaRongDao_Timer";
import ShuZiHuaRongDao_WinPanel from "./ShuZiHuaRongDao_WinPanel";
import { SSS_AudioManager } from 'db://assets/Script/Manager/SSS_AudioManager';

// // 慢一点执行
@ccclass('ShuZiHuaRongDaoGameManager')
@executionOrder(101)
export class ShuZiHuaRongDao_GameManager extends Component {
    static Instance: ShuZiHuaRongDao_GameManager;
    @property(Node)
    Root_block: Node | null = null;
    @property(Node)
    timer: Node | null = null;
    onLoad() {
        ShuZiHuaRongDao_GameManager.Instance = this;

        this.Init();
    }
    async Init() {
        ShuZiHuaRongDao_GameStorage.initData();
        ShuZiHuaRongDao_GameData.InitData();

        if (ShuZiHuaRongDao_GameStorage.data[ShuZiHuaRongDao_GameData.Game_mode].current_data.map.length === 0) {
            this.Init_map();
        }
        else {
            ShuZiHuaRongDao_GameData.ReadData();
        }

        ShuZiHuaRongDao_GamePanel.Instance.ShowOn();




        let timer = this.timer.getComponent(ShuZiHuaRongDao_Timer);
        timer.elapsedTime = ShuZiHuaRongDao_GameStorage.data[ShuZiHuaRongDao_GameData.Game_mode].current_data.time;
        timer.updateTimeLabel();



        // this.timer.getComponent(ShuZiHuaRongDao_Timer).startTimer();
    }
    async Init_map() {
        await this.Init_block();
        this.shuffleAndApply();

        ShuZiHuaRongDao_GameData.SaveData();
    }
    shuffleAndApply() {
        const colCount = ShuZiHuaRongDao_GameData.col;
        const rowCount = ShuZiHuaRongDao_GameData.row;
        const total = rowCount * colCount;

        // 构建数字列表（含 0）
        const numbers: number[] = [];
        for (let i = 1; i < total; i++) {
            numbers.push(i);
        }
        numbers.push(0); // 空格放最后

        // 洗牌，直到是可解的
        do {
            this.shuffle(numbers);
        } while (!this.isSolvable(numbers, colCount));

        // 重新赋值每个 block
        const blocks = ShuZiHuaRongDao_GameData.arrBlocks;

        for (let i = 0; i < blocks.length; i++) {
            const block = blocks[i];
            const id = numbers[i];

            const col = (i % colCount) + 1;
            const row = Math.floor(i / colCount) + 1;

            block.id = id;
            block.col = col;
            block.row = row;
            block.Refresh();
            block.MovePosition();
        }
    }
    shuffle(arr: number[]) {
        for (let i = arr.length - 1; i > 0; i--) {
            const j = Math.floor(Math.random() * (i + 1));
            [arr[i], arr[j]] = [arr[j], arr[i]];
        }
    }
    isSolvable(arr: number[], colCount: number): boolean {
        const invCount = this.getInversionCount(arr);

        if (colCount % 2 === 1) {
            // 奇数列数：逆序数为偶数即可
            return invCount % 2 === 0;
        } else {
            // 偶数列数：需要考虑空格在哪一行（从底部数起）
            const blankIndex = arr.indexOf(0);
            const rowFromBottom = Math.floor(blankIndex / colCount);
            return (invCount + rowFromBottom) % 2 === 1;
        }
    }
    getInversionCount(arr: number[]): number {
        let count = 0;
        for (let i = 0; i < arr.length; i++) {
            for (let j = i + 1; j < arr.length; j++) {
                if (arr[i] && arr[j] && arr[i] > arr[j]) {
                    count++;
                }
            }
        }
        return count;
    }
    async Init_block() {
        const row = ShuZiHuaRongDao_GameData.row;
        const col = ShuZiHuaRongDao_GameData.col;

        ShuZiHuaRongDao_GameData.arrBlocks = [];

        let id = 1;

        for (let r = 1; r <= row; r++) {
            for (let c = 1; c <= col; c++) {
                let num = id;
                if (r === row && c === col) {
                    num = 0; // 右下空格
                } else {
                    id++;
                }

                const block = await ShuZiHuaRongDao_GameFunction.CreateBlock(c, r, num);
                ShuZiHuaRongDao_GameData.arrBlocks.push(block);
            }
        }
    }
    //    // 是否正在动画中，防止重复点击
    private isAnimating = false;
    onBlockClick(block: ShuZiHuaRongDao_Block) {
        if (this.isAnimating) return;

        const emptyBlock = ShuZiHuaRongDao_GameData.arrBlocks.find(b => b.id === 0);
        if (!emptyBlock) return;

        if (this.isNeighbor(block.col, block.row, emptyBlock.col, emptyBlock.row)) {
            // console.log(`onBlockClick--------`);

            ShuZiHuaRongDao_GameStorage.data[ShuZiHuaRongDao_GameData.Game_mode].current_data.step_number++;
            if (!ShuZiHuaRongDao_GameData.game_start) {
                ShuZiHuaRongDao_GameData.game_start = true;

                this.timer.getComponent(ShuZiHuaRongDao_Timer).startTimer();
            }

            ShuZiHuaRongDao_GameStorage.saveData();

            ShuZiHuaRongDao_GamePanel.Instance.Refresh();


            bdlMgr.getRes<AudioClip>(SSS_Consts.BundleName.AUDIO, `audio/掉落音效`, AudioClip).then(res => {
                SSS_AudioManager.Instance.playSFX(res, false);
            });


            this.isAnimating = true;

            // 交换行列
            const tempCol = block.col;
            const tempRow = block.row;
            block.col = emptyBlock.col;
            block.row = emptyBlock.row;
            emptyBlock.col = tempCol;
            emptyBlock.row = tempRow;




            // 动画移动，移动完成后恢复状态
            Promise.all([
                block.MovePosition(0.1),
                emptyBlock.MovePosition(0.1)
            ]).then(() => {
                this.isAnimating = false;

                ShuZiHuaRongDao_GameData.SaveData();

                this.checkWin();
            });
        }
    }
    isNeighbor(c1: number, r1: number, c2: number, r2: number): boolean {
        return Math.abs(c1 - c2) + Math.abs(r1 - r2) === 1;
    }
    checkWin() {
        // 判断是否所有块都在正确位置
        for (const block of ShuZiHuaRongDao_GameData.arrBlocks) {
            // 空格忽略位置判断
            if (block.id === 0) continue;

            // 期望位置
            const expectedId = (block.row - 1) * ShuZiHuaRongDao_GameData.col + block.col;
            if (block.id !== expectedId) {
                return false;
            }
        }
        console.log("游戏胜利！");

        this.Win();

        return true;
    }
    async Win() {
        ShuZiHuaRongDao_GameData.game_start = false;
        this.timer.getComponent(ShuZiHuaRongDao_Timer).stopTimer();

        // console.log(`this.timer.getComponent(ShuZiHuaRongDao_Timer).elapsedTime`, this.timer.getComponent(ShuZiHuaRongDao_Timer).elapsedTime)

        if (ShuZiHuaRongDao_GameStorage.data[ShuZiHuaRongDao_GameData.Game_mode].best_time < 0 ||
            ShuZiHuaRongDao_GameStorage.data[ShuZiHuaRongDao_GameData.Game_mode].best_time > this.timer.getComponent(ShuZiHuaRongDao_Timer).elapsedTime
        ) {
            ShuZiHuaRongDao_GameStorage.data[ShuZiHuaRongDao_GameData.Game_mode].best_time = this.timer.getComponent(ShuZiHuaRongDao_Timer).elapsedTime;
            ShuZiHuaRongDao_GameStorage.data[ShuZiHuaRongDao_GameData.Game_mode].step_number = ShuZiHuaRongDao_GameData.step_number;
            ShuZiHuaRongDao_GameStorage.saveData();
        }

        await UI.Instance.CreatePanel_sub(`ShuZiHuaRongDao_Prefab`, `UI/ShuZiHuaRongDao_WinPanel`, ShuZiHuaRongDao_WinPanel);


        ShuZiHuaRongDao_GameStorage.data[ShuZiHuaRongDao_GameData.Game_mode].current_data = {
            map: [],
            time: 0,
            step_number: 0,
        }
        ShuZiHuaRongDao_GameStorage.saveData();
    }
    Replay() {
        ShuZiHuaRongDao_GameData.ClearData();

        let currentSceneName = director.getScene().name;
        director.loadScene(currentSceneName);
    }
}